<?php

namespace App\Logics;

//use Mews\Captcha\Facades\Captcha;
use App\Models\SiteCode;
use App\Models\User;
use Illuminate\Support\Facades\Crypt;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Mail;
use App\Service\Email;
use Illuminate\Support\Str;


class AccountLogic extends Logic
{

    // 修改
    public function edit($myUser, $options = [])
    {
        $opt  = $this->option();
        $data = [
            //'username' => $opt->getData('username', null, 'trim'),
            //'role'     => $opt->getData('role', null, 'trim'),
            'nickname' => $opt->getData('nickname', null, 'trim'),
            'password' => $opt->getData('password', null, 'trim'),
            'mobile'   => $opt->getData('mobile', null, 'trim'),
            //'status'   => $opt->getData('status', 1, 'intval),
        ];

        // 参数
        $is_admin_log = $options['is_admin_log'] ?? 0;

        // 检查唯一性
        $model = new User();
        $data  = $model->filterField($data, true);
        if(empty($data)){
            //return $this->_returnFail('不能修改为空！');
            return $this->_returnFail('send_data_to_be_modify');
        }

        // 检查唯一性
        $data = $model->checkUser($data, $myUser['id']);
        if(empty($data)){
            //return $this->_returnFail('不能修改为空！');
            return $this->_returnFail('send_data_to_be_modify');
        }

        // 验证
        $where  = ['id' => $myUser['id']];
        $result = $model->oneEdit($where, $data);
        if($result === false){
            return $this->_returnFail($model->getError());
        }


        return true;
    }

    // 修改密码
    public function password($myUser)
    {
        $opt      = $this->option();
        $password = $opt->getData('password', null, 'trim');
        $code     = $opt->getData('code', null, 'trim');
        if(empty($code)){
            return $this->_returnFail('enter_the_verification_code');
            //return $this->_returnFail('请输入验证码！');
        }
        if(empty($password)){
            //return $this->_returnFail('密码不能为空！');
            return $this->_returnFail('send_data_to_be_modify');
        }

        // 验证码
        $codeDb = new SiteCode();
        $cWhere = [["email", '=', $myUser['email']], ["ctime", '>=', strtotime("today")], ['status', '=', 0]];
        $lists  = $codeDb->getList($cWhere, 1, 'id DESC');
        if(empty($lists)){
            return $this->_returnFail('Captcha_error');
            //return $this->_returnFail('验证码错误！');
        }
        if($lists[0]['ctime'] + 600 < LARAVEL_TIME){
            return $this->_returnFail('verification_code_timed_out');
            //return $this->_returnFail('验证码超时！');
        }
        if($lists[0]['code'] != $code){
            return $this->_returnFail('Captcha_error');
            //return $this->_returnFail('验证码错误！');
        }
        // 验证码 已经使用
        $codeDb->where('id', $lists[0]['id'])->update(['status' => 1]);

        $model = new User();
        $data  = ['password' => $password,];
        $data  = $model->checkData($data);

        $where  = ['id' => $myUser['id']];
        $result = $model->oneEdit($where, $data);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return true;
    }

    // 忘记密码 验证邮件后更新密码  删除token，重新登录
    public function forget()
    {
        // 验证
        $opt      = $this->option();
        $email    = $opt->getData('email', null, 'trim');
        $password = $opt->getData('password', null, 'trim');
        $code     = $opt->getData('code', null, 'trim');
        $onlineip = $opt->getIp();
        if(empty($code)){
            return $this->_returnFail('enter_the_verification_code');
            //return $this->_returnFail('请输入验证码！');
        }
        if(empty($password)){
            //return $this->_returnFail('密码不能为空！');
            return $this->_returnFail('send_data_to_be_modify');
        }
        if(empty($email) || empty($password)){
            //return $this->_returnFail('邮箱和密码不能为空！');
            return $this->_returnFail('Email_and_password_cannot_be_empty');
        }

        // 验证码
        $codeDb = new SiteCode();
        $cWhere = [["email", '=', $email], ["ctime", '>=', strtotime("today")], ['status', '=', 0]];
        $lists  = $codeDb->getList($cWhere, 1, 'id DESC');
        if(empty($lists)){
            return $this->_returnFail('Captcha_error');
            //return $this->_returnFail('验证码错误！');
        }
        if($lists[0]['ctime'] + 600 < LARAVEL_TIME){
            return $this->_returnFail('verification_code_timed_out');
            //return $this->_returnFail('验证码超时！');
        }
        if($lists[0]['code'] != $code){
            return $this->_returnFail('Captcha_error');
            //return $this->_returnFail('验证码错误！');
        }
        // 验证码 已经使用
        $codeDb->where('id', $lists[0]['id'])->update(['status' => 1]);


        $model   = new User();
        $salt    = Str::random(4);
        $newPass = $model->add_md5($password, $salt);
        $data    = ['password' => $newPass, 'salt' => $salt,];
        //$data    = $model->checkData($data);

        // 用户
        $info = $model->oneFind(['email' => $email]);
        if(empty($info)){
            //return $this->_returnFail('邮箱不存在！');
            return $this->_returnFail('email_has_not_exist');
        }

        $where  = ['id' => $info['id']];
        $result = $model->oneEdit($where, $data);
        if($result === false){
            return $this->_returnFail($model->getError());
        }

        return true;
    }

    // 登录
    public function login()
    {
        // 验证
        $opt      = $this->option();
        $email    = $opt->getData('email', null, 'trim');
        $password = $opt->getData('password', null, 'trim');
        $onlineip = $opt->getIp();

        // 登录操作
        $model = new User();
        $user  = $model->login($email, $password, 'email');
        if($user === false){
            return $this->_returnFail($model->getError());
        }


        // 返回
        $info  = ['id' => $user['id'], 'username' => $user['username'], 'ctime' => LARAVEL_TIME,];
        $token = $opt->setToken($info, 'user');
        //$token = Crypt::encryptString(json_encode($info, JSON_UNESCAPED_UNICODE));
        // 权限整理
        $user['uid'] = $user['id'];
        // 整理返回
        $result = ['token' => $token, 'user' => $user,];

        return $result;
    }

    // 注册
    public function reg()
    {
        // 验证
        $opt      = $this->option();
        $email    = $opt->getData('email', null, 'trim');
        $password = $opt->getData('password', null, 'trim');
        $code     = $opt->getData('code', null, 'trim');
        $onlineip = $opt->getIp();
        if(empty($code)){
            return $this->_returnFail('enter_the_verification_code');
            //return $this->_returnFail('请输入验证码！');
        }
        if(empty($email) || empty($password)){
            //return $this->_returnFail('邮箱和密码不能为空！');
            return $this->_returnFail('Email_and_password_cannot_be_empty');
        }

        // 验证码
        $codeDb = new SiteCode();
        $cWhere = [["email", '=', $email], ["ctime", '>=', strtotime("today")], ['status', '=', 0]];
        $lists  = $codeDb->getList($cWhere, 1, 'id DESC');
        if(empty($lists)){
            return $this->_returnFail('Captcha_error');
            //return $this->_returnFail('验证码错误！');
        }
        if($lists[0]['ctime'] + 600 < LARAVEL_TIME){
            return $this->_returnFail('verification_code_timed_out');
            //return $this->_returnFail('验证码超时！');
        }
        if($lists[0]['code'] != $code){
            return $this->_returnFail('Captcha_error');
            //return $this->_returnFail('验证码错误！');
        }
        // 验证码 已经使用
        $codeDb->where('id', $lists[0]['id'])->update(['status' => 1]);

        // 登录操作
        $model = new User();
        $user  = $model->reg($email, $password, 'email');
        if($user === false){
            return $this->_returnFail($model->getError());
        }


        // 返回
        $info  = ['id' => $user['id'], 'email' => $email, 'ctime' => LARAVEL_TIME,];
        $token = $opt->setToken($info, 'user');
        //$token = Crypt::encryptString(json_encode($info, JSON_UNESCAPED_UNICODE));
        // 权限整理
        $user['uid'] = $user['id'];
        // 整理返回
        $result = ['token' => $token, 'user' => $user,];

        return $result;
    }

    // 发送验证码
    // 发送邮件验证码
    public function sendEmail()
    {
        $timeout = 300; // 超时时间 5分钟
        $timeout = 60; // 超时时间 5分钟
        $opt     = $this->option();
        $email   = $opt->getData('email', null, 'trim');
        $isReg   = $opt->getData('is_reg', 0, 'intval');  // 是否是注册
        if(empty($email)){
            return $this->_returnFail('Email_cannot_be_empty');
            //return $this->_returnFail('邮箱不能为空！');
        }
        if(!filter_var($email, FILTER_VALIDATE_EMAIL)){
            return $this->_returnFail('enter_the_correct_email_address');
            //return $this->_returnFail('请输入正确邮箱地址！');
        }

        // 验证邮箱是否已经注册
        $userDb = new User();
        $where  = [['email', '=', $email], ['status', '>=', 0]];
        $info   = $userDb->where($where)->first(); // ->recycle()
        if($isReg){
            // 注册的时候
            if(!empty($info)){
                return $this->_returnFail('email_already_been_registered');
                //return $this->_returnFail('该邮箱已经注册！');
            }
        } else{
            // 忘记密码的时候
            if(empty($info)){
                return $this->_returnFail('email_is_not_registered');
                //return $this->_returnFail('该邮箱没有注册！');
            }
            if($info->status == 0){
                return $this->_returnFail('the_user_has_been_disabled');
                //return $this->_returnFail('对不起，该用户已经被禁用！！');
            }
        }


        // 发送短信是否满了
        $codeDb = new SiteCode();
        $where  = [["email", '=', $email], ["ctime", '>=', strtotime("today")]];
        $lists  = $codeDb->getList($where, 0, 'id DESC');
        $lists  = is_object($lists) ? $lists->toArray() : $lists;
        if($lists){
            /*if(count($lists) >= 10){
                return $this->_returnFail('对不起，超过当日可发条数！！');
            }*/
            if($lists[0]['ctime'] >= LARAVEL_TIME - $timeout){
                return $this->_returnFail('Try_again_in_minutes');
                //return $this->_returnFail('1分钟后再试！！');
            }
        }

        // 发送验证码
        $code = rand(1000, 9999);
        try{
            //使用blade模板发送(引用的模板)
            // Mail::send(模板文件, [参数], function($message) use ($email) {});
            Mail::send('emails.slhemail', ['code' => $code], function($message) use ($email) {
                $message->to($email)->subject('Little Rascal');
            });
        } catch(\Exception $e){
            Log::info('发送邮件失败 | '.var_export($e->getMessage(), 1));

            return $this->_returnFail('Failed_to_send_verification_code_email');
            //return $this->_returnFail('发送验证码邮件失败！');
        }
        /*$failures = Mail::failures();
        if($failures){
            Log::info('发送邮件失败 | '.var_export($failures, 1));
            if(empty($failures[0])){
                return $this->_returnFail('发送验证码邮件失败！');
            } else{
                return $this->_returnFail($failures[0].'！');
            }
        }*/

        // 将验证码保存到数据库
        $add = ["email" => $email, "code" => $code, "ip" => $opt->getIp(), "status" => "0", "ctime" => LARAVEL_TIME];
        $res = $codeDb->oneAdd($add);
        if($res === false){
            return $this->_returnFail($codeDb->getError());
        }

        return $code;
    }

    // 生成token
    public function token()
    {
        $opt = $this->option();
        $uid = $opt->getData('uid', 0, 'intval');

        $userDb = new User();
        $field  = ['id', 'email', 'status', 'mobile',];
        $info   = $userDb->where(['id' => $uid])->select($field)->first(); // ->recycle()
        if($info === false){
            return $this->_returnFail($userDb->getError());
        }
        if(empty($info)){
            //return $this->_returnFail('用户不存在！！');
            return $this->_returnFail('user_has_no_exist');
        }
        if($info->status === 0){
            //return $this->_returnFail('用户被禁用！！');
            return $this->_returnFail('user_has_not_exist_or_has_been_disabled');
        }

        $user   = ['id' => $info->id, 'email' => $info->email, 'ctime' => LARAVEL_TIME,];
        $info   = $info->toArray();
        $token  = Crypt::encryptString(json_encode($user, JSON_UNESCAPED_UNICODE));
        $result = ['token' => $token, 'user' => $info,];

        return $result;
    }


}

